﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Transactions;
using GameDb.Entities;

namespace GameDb
{
    public static class GameCtx
    {
        public static Func<string> GetCurrentUserName;
        public static string ConnectionString = ConfigurationManager.ConnectionStrings["GameDbContext"].ConnectionString;
        public static T Use<T>(Func<GameDbContext, T> callback)
        {
            using (var ctx = new GameDbContext())
            {
                return callback(ctx);
            }
        }

        public static T Use<T>(Func<GameDbContext, TransactionScope, T> callback)
        {
            using (var ts = new TransactionScope())
            {
                using (var ctx = new GameDbContext())
                {
                    var outval = callback(ctx, ts);
                    ts.Complete();
                    return outval;
                }
            }
        }

        public static Game GetGameRecord()
        {
            return GameCtx.Use(
                ctx =>
                {
                    return GetGameRecord(ctx);
                });
        }
        public static Game GetGameRecord(GameDbContext ctx)
        {
            var cbd = ctx.Games.Where(gm => gm.GameName == "cellblock-d").ToList();
            if (cbd.Count > 0)
                return cbd[0];
            return CreateSeedGame(ctx);
        }

        private static Game CreateSeedGame(GameDbContext ctx)
        {
            var game = new Game { GameName = "cellblock-d" };
            ctx.Games.Add(game);
            ctx.SaveChanges();
            return game;
        }

        public static User GetCurrentUser(GameDbContext ctx)
        {
            var curUser = GetCurrentUserName();
            return ctx.Users.Where(usr => usr.Username == curUser).Single();
        }

        public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
        {
            T[] elements = source.ToArray();
            // Note i > 0 to avoid final pointless iteration
            for (int i = elements.Length - 1; i > 0; i--)
            {
                // Swap element "i" with a random earlier element it (or itself)
                int swapIndex = rng.Next(i + 1);
                yield return elements[swapIndex];
                elements[swapIndex] = elements[i];
                // we don't actually perform the swap, we can forget about the
                // swapped element because we already returned it.
            }

            // there is one item remaining that was not returned - we return it now
            yield return elements[0];
        }
    }
}
